package com.baimsg.reader.network

import com.baimsg.reader.Constant
import com.baimsg.reader.util.Log
import okhttp3.FormBody
import okhttp3.Headers.Companion.toHeaders
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.IOException

object HttpUtils {

    val client by lazy {
        OkHttpClient.Builder().build()
    }

    /**
     * 发送 GET请求
     *
     * @param url 链接
     * @return 请求结果
     */
    fun exeGet(
        url: String,
        headers: Map<String, String> = mutableMapOf("Connection" to "close")
    ): String? {
        val request = Request.Builder()
            .get()
            .url(url)
            .headers(headers.toHeaders())
            .build()
        return exe(request)
    }

    /**
     * 发起 POST请求
     *
     * @param url  链接
     * @param form 表单集合
     * @return 请求结果
     */
    @JvmOverloads
    fun exePost(
        url: String,
        form: Map<String, String>,
        headers: Map<String, String> = hashMapOf("Connection" to "close")
    ): String? {
        val formBody = FormBody.Builder()
        for ((key, value) in form) {
            formBody.add(key, value)
        }
        val request = Request.Builder()
            .post(formBody.build())
//            .method("POST", formBody.build())
            .url(url)
            .headers(headers.toHeaders())
            .build()
        return exe(request)
    }

    /**
     * 发起 POST请求
     *
     * @param url  链接
     * @param json json数据
     * @return 请求结果
     */
    @JvmOverloads
    fun exePost(
        url: String,
        json: String,
        headers: Map<String, String> = hashMapOf("Connection" to "close")
    ): String? {
        val mediaType = "application/json;charset=utf-8".toMediaTypeOrNull()
        val body = json.toRequestBody(mediaType)
        val request = Request.Builder()
            .post(body)
            .url(url)
            .headers(headers.toHeaders())
            .build()
        return exe(request)
    }

    /**
     * 发起同步请求
     *
     * @param request 请求数据
     * @return 请求结果
     */
    private fun exe(request: Request): String? {
        for (i in 1..Constant.retry) {
            if (i != 1) Log.d("${request.url} 第${i}次重试ing...")
            try {
                val exe = client.newCall(request).execute()
                val body = exe.body
                if (exe.isSuccessful) {
                    return body?.string() ?: "null"
                }
            } catch (e: IOException) {
                e.message
            }
        }
        Log.e("${request.url} 连接失败！")
        return null
    }
}